package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.BankAccount;
import com.ruoyi.bizsys.domain.BankAccountLog;
import com.ruoyi.bizsys.domain.CustBvnMatch;
import com.ruoyi.bizsys.domain.RealNameAuth;
import com.ruoyi.bizsys.mapper.BankAccountMapper;
import com.ruoyi.bizsys.service.IBankAccountLogService;
import com.ruoyi.bizsys.service.IBankAccountService;
import com.ruoyi.bizsys.service.IRealNameAuthService;
import com.ruoyi.bizsys.vo.BankAccountVo;
import com.ruoyi.business.common.constant.KycApiEnum;
import com.ruoyi.business.service.IAppBankAccountService;
import com.ruoyi.business.service.IPayTransService;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.business.CheckAccountNameUtil;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class AppBankAccountServiceImpl implements IAppBankAccountService {

    @Autowired
    BankAccountMapper bankAccountMapper;

    @Autowired
    IBankAccountLogService bankAccountLogService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Autowired
    private IPayTransService payTransService;

    @Autowired
    private IRealNameAuthService realNameAuthService;

    private IBankAccountService bankAccountService;

    /**
     * account 提示
     */
    public static final String ACCOUNT_MSG_BEGIN = "Incorrect account, please bind your own account,";

    /**
     * account 提示
     */
    public static final String ACCOUNT_MSG_END = " chance(s) remaining.";


    @Override
    public void insertBankAccount(BankAccount bankAccount) {
        //获取 账户绑定次数 ，判断是否大于当日提交的次数
        //获取配置的提交次数
        int maxBindNum = Integer.valueOf(sysDictDataService.selectDictLabel("bind_account_number", "num"));
        int bindAccountNum = bankAccountLogService.selectBindAccountNumByUserId(bankAccount.getUserId());
        if (bindAccountNum >= maxBindNum) {
            throw new BusinessException(RspEnmu.BINDING_TIMES_EXCEEDED);
        }
        BankAccount bank = new BankAccount();
        bank.setAccountNumber(bankAccount.getAccountNumber());
        bank.setState("0");
        int accountSize = bankAccountMapper.selectCountByUserId(bank);
        if (accountSize > 0) {
            bankAccount.setRemark("Repeat binding");
            insertBankAccountLog(bankAccount);
            throw new BusinessException(RspEnmu.REPEAT_BINDING);
        }
        try {
            //调用payStackAccount 校验
            String accountName = payTransService.checkAccountNumber(bankAccount.getAccountNumber(), bankAccount.getBankCode());
            //获取用户实名信息
            RealNameAuth realNameAuth = realNameAuthService.selectRealNameAuthByCustNo(bankAccount.getCustNo());
            if (null == accountName) {
                payTransService.verifyBVNMatch(bankAccount.getAccountNumber(), realNameAuth.getBvnAccount(), bankAccount.getBankCode(), realNameAuth.getUserId());
                bankAccount.setRemark("Account name is not found");
                insertBankAccountLog(bankAccount);
                throw new BusinessException(ACCOUNT_MSG_BEGIN + (maxBindNum - bindAccountNum - 1) + ACCOUNT_MSG_END);
            }
            boolean verifyRes = accountVerify(accountName, bankAccount.getAccountNumber(), bankAccount.getBankCode(), realNameAuth);

            if (!verifyRes) {
                bankAccount.setRemark("name Verification failed");
                insertBankAccountLog(bankAccount);
                throw new BusinessException(ACCOUNT_MSG_BEGIN + (maxBindNum - bindAccountNum - 1) + ACCOUNT_MSG_END);

            }
            bankAccount.setRemark("Success");
            insertBankAccountLog(bankAccount);
            bankAccountMapper.insertBankAccount(bankAccount);
        } catch (Exception e) {
            log.error("------- account verify check error:", e);
            if (e instanceof BusinessException) {
                BusinessException exception = (BusinessException) e;
                if (null != exception.getCode() && exception.getCode() == 300027) {
                    bankAccount.setRemark("Verification failed");
                    insertBankAccountLog(bankAccount);
                }
                throw new BusinessException(ACCOUNT_MSG_BEGIN + (maxBindNum - bindAccountNum - 1) + ACCOUNT_MSG_END);
            }
            throw new BusinessException(RspEnmu.NETWORK_BUSY);
        }
    }

    @Override
    public int selectCountByUserId(BankAccount account) {
        account.setState("0");
        return bankAccountMapper.selectCountByUserId(account);
    }

    @Override
    public int updateBankAccountIsDefault(BankAccount account) {
        return bankAccountMapper.updateBankAccountIsDefault(account);
    }

    @Override
    public List<BankAccountVo> selectBankAccountListByUserId(BankAccount bankAccount) {
        return bankAccountMapper.selectBankAccountAndNameList(bankAccount);
    }

    @Override
    public boolean accountVerify(String sourceFullName, String sourceAccount, String bankCode, RealNameAuth realNameAuth) {
        //姓名校验
        String basisName = realNameAuth.getFirstName().trim() + " "
                + realNameAuth.getMiddleName().trim() + " " + realNameAuth.getLastName().trim();
        boolean isMatch = CheckAccountNameUtil.verifyName(sourceFullName, basisName);
        boolean apiSwitch = isMatch ? kycApiSwitch(KycApiEnum.PAY_STACK_BVN_MATCH) : kycApiSwitch(KycApiEnum.PAY_STACK_BVN_MATCH_CHECK_NAME);
        //开关关闭或者bankCode为空 则以姓名匹配结果为准
        if (!apiSwitch || Func.isEmpty(bankCode)) {
            return isMatch;
        }
        //BvnMatch
        return bVNMatchVerify(sourceAccount,
                realNameAuth.getBvnAccount(), bankCode, realNameAuth.getUserId());
    }

    @Override
    public void appendAccount(String userId) {
        RealNameAuth realNameAuth = realNameAuthService.getOne(new QueryWrapper<RealNameAuth>().eq("user_id", userId));
        //实名没有Account直接跳过
        if (Func.isEmpty(realNameAuth.getAccountNumber())) {
            return;
        }
        //Account接口不需要验证
        String[] split = realNameAuth.getExqApi().split(",");
        String apiName = split[split.length - 1];
        if (StringUtils.equalsAny(apiName, "Lookup-Account-Mid", "NUBAN-Identity-Verification,NUBAN-Identity-Verification-back")) {
            bankAccountService.saveByRealNameAuth(realNameAuth);
            return;
        }
        //校验
        //调用payStackAccount 校验
        String accountName = payTransService.checkAccountNumber(realNameAuth.getAccountNumber(), realNameAuth.getBankCode());
        boolean verifyRes = accountVerify(accountName, realNameAuth.getAccountNumber(), realNameAuth.getBankCode(), realNameAuth);
        if (verifyRes) {
            log.info("用户:{},实名新品Account:{}成功.", userId, realNameAuth.getAccountNumber());
            bankAccountService.saveByRealNameAuth(realNameAuth);
        }
        log.info("用户:{},实名新品Account:{}失败.", userId, realNameAuth.getAccountNumber());
    }

    public static void main(String[] args) {
        String basisName = "David".trim() + " " + "Goke".trim();
        String fullBame = "OBOZUWA".trim() + " " + "DA".trim() + " " + "GO";
        boolean isMatch = CheckAccountNameUtil.verifyName(fullBame, basisName);
        System.err.println(isMatch);

    }

    @Override
    public boolean bVNMatchVerify(String account, String bvn, String bankCode, String userId) {
        CustBvnMatch custBvnMatch = payTransService.verifyBVNMatch(account, bvn, bankCode, userId);
        if ("true".equals(custBvnMatch.getIsBlacklisted())) {
            log.info("BvnMatch:用户 {} Account进入黑名单 保存失败。", userId);
            return false;
        }
        if (Func.isEmpty(custBvnMatch.getAccountNumber()) || "false".equals(custBvnMatch.getAccountNumber())) {
            log.info("BvnMatch:用户 {} accountNumber不匹配 保存失败。", userId);
            return false;
        }
        return true;
    }


    void insertBankAccountLog(BankAccount bankAccount) {
        BankAccountLog bankAccountLog = new BankAccountLog();
        bankAccountLog.setCustNo(bankAccount.getCustNo());
        bankAccountLog.setUserId(bankAccount.getUserId());
        bankAccountLog.setAccountNumber(bankAccount.getAccountNumber());
        bankAccountLog.setBankCode(bankAccount.getBankCode());
        bankAccountLog.setRemark(bankAccount.getRemark());
        bankAccountLogService.insertBankAccountLog(bankAccountLog);
    }

    /**
     * 接口开关
     *
     * @param apiEnum
     * @return
     */
    public boolean kycApiSwitch(KycApiEnum... apiEnum) {
        String[] values = new String[apiEnum.length];
        for (int i = 0; i < apiEnum.length; i++) {
            values[i] = apiEnum[i].getValue();
        }
        List<String> labels = sysDictDataService.selectDictLabel(apiEnum[0].getType(), values);
        return labels.size() > 0 && labels.contains("1");
    }

}
